#include "head.h"
#define RECV_SUCCESS 0
int recvn(int sockfd, void *buf, int length);

void sendCommand(int netFd, commandType type, const char *data) {
    TLVtrain_t tlv;
    tlv.type = type;
    strncpy(tlv.data, data, sizeof(tlv.data) - 1);
    tlv.length = strlen(tlv.data);
    printf("[DEBUG-CLIENT] Send: type=%d, length=%d, data=%s\n", tlv.type, tlv.length, tlv.data);
    send(netFd, &tlv.type, sizeof(tlv.type), MSG_NOSIGNAL);
    send(netFd, &tlv.length, sizeof(tlv.length), MSG_NOSIGNAL);
    send(netFd, tlv.data, tlv.length, MSG_NOSIGNAL);
}

int recvResponse(int netFd, char *buf, size_t bufSize) {
    int len = 0;
    if (recvn(netFd, &len, sizeof(len)) != 0){
        printf("[DEBUG-CLIENT] Failed to receive length\n");
        return -1;}
    if (len > 0) {
        if ((size_t)len >= bufSize){
            len = bufSize - 1;}
        if (recvn(netFd, buf, len) != 0){
            printf("[DEBUG-CLIENT] Failed to receive length\n");
            return -1;}
        buf[len] = '\0';}
    else {
        buf[0] = '\0';
    }
    return len;
}

int workCmd(int netFd) {
    // 初始化名字
    printf("Plz enter user name:");
    char name[50];
    scanf("%s", name);

    train_t train;
    train.length = strlen(name);
    memcpy(train.data, name, train.length);
    /* printf("%d ,%s\n",train.length,train.data); */
    send(netFd, &train.length, sizeof(train.length), MSG_NOSIGNAL);
    send(netFd, train.data, train.length, MSG_NOSIGNAL);

    client_t *client = (client_t *)calloc(1, sizeof(client_t));
    client->fd = netFd;
    memcpy(client->userName, train.data, train.length);

    // 初始地址 ./
    strcpy(client->pwd, "./");
    while (1) {
        printf("%s$ \n", client->pwd);
        fflush(stdout);

        // 获取命令
        char temp[1024] = {0};
        read(STDIN_FILENO, temp, sizeof(temp));
        temp[strlen(temp) - 1] = 0;

        // 分离命令
        char cmd[1024] = {0};
        char args[1024] = {0};
        char *p = temp;
        while (*p == ' ' || *p == '\t') {
            ++p;
        }

        char *saveptr = NULL;
        // 拿到命令(cd,ll,ls...)
        char *token = strtok_r(p, " \t\n", &saveptr);

        if (token) {
            strncpy(cmd, token, sizeof(cmd) - 1);
            char *arg_ptr = args;
            while ((token = strtok_r(NULL, " \t\n", &saveptr))) {
                int len = strlen(token);
                if ((arg_ptr - args) + len < sizeof(args)) {
                    memcpy(arg_ptr, token, len);
                    arg_ptr += len;
                }
            }
            *arg_ptr = '\0';
        } else {
            cmd[0] = '\0';
            args[0] = '\0';
        }
        printf("  Cmd: [%s], Arg: [%s]\n", cmd, args);

        if (strncmp("cd", cmd, 2) == 0) {
            // 发送目标路径
            sendCommand(netFd, CD, args);
            // 接收新路径
            char reply[1024] = {0};
            int ret = recvResponse(netFd, reply, sizeof(reply)); // 接收回应
            if (ret > 0 && strncmp(reply, "cd success", 10) == 0) {
                // 服务端确认存在目录，我们才更新路径
                strncpy(client->pwd, args, sizeof(client->pwd) - 1);
            } else {
                // 输出服务端返回的错误信息
                printf("Server: %s\n", reply);
            }

        } else if (strcmp("ls", cmd) == 0) {
            sendCommand(netFd, LS, args);

            char dirName[1024] = {0};
            int dirLength = 0;
            while (1) {
                bzero(dirName, sizeof(dirName));
                if(recvn(netFd, &dirLength, sizeof(int))!=RECV_SUCCESS)break;
                if(recvn(netFd, dirName, dirLength)!=RECV_SUCCESS)break;
                if (dirLength == 0) {
                    break;
                }
                printf("%s\t", dirName);
            }
            printf("\n");
        } else if (strcmp("ll", cmd) == 0) {
            sendCommand(netFd, LL, args);

            char dirInfo[1024] = {0};
            int infoLength = 0;
            while (1) {
                bzero(dirInfo, sizeof(dirInfo));
                if(recvn(netFd, &infoLength, sizeof(int)) != RECV_SUCCESS)break;
                if(recvn(netFd, dirInfo, infoLength)!=RECV_SUCCESS)break;
                if (infoLength == 0) {
                    break;
                }
                printf("%s\n", dirInfo);
            }
            printf("\n");
        } else if (strcmp("pwd", cmd) == 0) {
            printf("%s\n", client->pwd);
        } else if (strncmp("puts", cmd, 4) == 0) {
            sendCommand(netFd, PUTS, args);
            sendFile(netFd,args);
        } else if (strncmp("gets", cmd, 4) == 0) {
            sendCommand(netFd, GETS, args);
            recvFile(netFd);
        } else if (strncmp("remove", cmd, 6) == 0) {
            sendCommand(netFd, REMOVE, args);
            char reply[1024] = {0};
            if (recvResponse(netFd, reply, sizeof(reply)) > 0) {
                printf("Server: %s\n", reply);
            }
        } else if (strncmp("mkdir", cmd, 5) == 0) {
            sendCommand(netFd, MKDIR, args);
            char reply[1024] = {0};
            if (recvResponse(netFd, reply, sizeof(reply)) > 0) {
                printf("Server: %s\n", reply);
            }
        } else if (strncmp("rmdir", cmd, 2) == 0) {
            sendCommand(netFd, RMDIR, args);
            char reply[1024] = {0};
            if (recvResponse(netFd, reply, sizeof(reply)) > 0) {
                printf("Server: %s\n", reply);
            }
        } else if (strcmp("quit", cmd) == 0) {
            sendCommand(netFd, QUIT, args);
            printf("Bye-bye!\n");
            break;
        } else {
            // 命令输入错误
            printf("Plz input right cmd or 'quit'.\n");
        }
    }
    return 0;
}


